﻿#include <Sys\IREBDERPIPE.HPP>
#include <SLIST.HPP>


using namespace CxxlMan;
using namespace Cxxl3D;

class CRenderPipe:public IRenderPipe
{
  CriticalSec csObject;
  bool isModify;

  SList<IRDpkg,false> m_IRDpkg_sList;
  Smart_Ptr<cxxlList<IRenderDatagram> > IRenderDatagram_List; // 保存 m_IRenderDatagram_sList.cxxlList_Create()，若沒改變就直接回傳，以加快速度


  virtual Smart_Ptr<cxxlList<IRenderDatagram> > cxxlFASTCALL GetIRenderDatagramList()
  {
    CriticalSecHandle AutoCSH(csObject);

    if(isModify)
    {
      IRenderDatagram_List->ClearAll();

      Smart_Ptr<IRDpkg> IRDpkg_Ptr = m_IRDpkg_sList.GetObj_Front();
      while(IRDpkg_Ptr.isNULL() == false)
      {
        IRenderDatagram_List->Push_Back(IRDpkg_Ptr->Get_IRenderDatagram());
        IRDpkg_Ptr = m_IRDpkg_sList.GetObj_Next(IRDpkg_Ptr);
      }

      isModify = false;
    }

    return IRenderDatagram_List;
  }

  // 加入
  virtual bool cxxlFASTCALL Add(const CxxlMan::Smart_Ptr<IRDpkg> &IRenderUnit_Arg)
  {
    CriticalSecHandle AutoCSH(csObject);
    isModify = true;
    return m_IRDpkg_sList.Push_Back(IRenderUnit_Arg);
  }

  // 將物件放入 refObj_Ptr 之前
  // 失敗表示要放入的物件已放入過了，或是 refObj_Ptr 不存在
  bool cxxlFASTCALL Add_Prev(const CxxlMan::Smart_Ptr<IRDpkg> &addObj_Ptr, const CxxlMan::Smart_Ptr<IRDpkg> &refObj_Ptr)
  {
    CriticalSecHandle AutoCSH(csObject);
    isModify = true;
    return m_IRDpkg_sList.Add_Prev(addObj_Ptr,refObj_Ptr);
  }

  // 將物件放入 refObj_Ptr 之後
  // 失敗表示要放入的物件已放入過了，或是 refObj_Ptr 不存在
  bool cxxlFASTCALL Add_Next(const CxxlMan::Smart_Ptr<IRDpkg> &addObj_Ptr, const CxxlMan::Smart_Ptr<IRDpkg> &refObj_Ptr)
  {
    CriticalSecHandle AutoCSH(csObject);
    isModify = true;
    return m_IRDpkg_sList.Add_Next(addObj_Ptr,refObj_Ptr);
  }


  // 移除
  virtual void cxxlFASTCALL Del(const CxxlMan::Smart_Ptr<IRDpkg> &IRenderUnit_Arg)
  {
    CriticalSecHandle AutoCSH(csObject);
    isModify = true;
    m_IRDpkg_sList.Delete(IRenderUnit_Arg);
    csObject.Leave();
  }

public:
  // Constructor
  CRenderPipe()
    :cxxlObject(CxxlMan::Spirit_Easy),
    IRenderDatagram_List(new cxxlList<IRenderDatagram>(this->GetSpirit()), this)
  {
    isModify = true;
  }

  // Destructor
  virtual ~CRenderPipe()
  {}

};

cxxlObject * new_CRenderPipe()
{
  return new CRenderPipe;
}

/*
// CentralizedMgr 會經由這個管道得到所要求的元件
extern "C" CXXL_DLLEXPORT
cxxlObject * cxxlCDECL CxxlMan_ObjectFactory(const wchar_t *ClassID, void *Arg, ISpirit *spirit)
{
  if(wcscmp(IRenderPipe_ClassID, ClassID) == 0)
    return new CRenderPipe;

  return NULL;
}
*/
